package peace.htmllooker
{

import flash.display.DisplayObject;
import flash.display.Sprite;
import flash.events.ErrorEvent;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.events.SecurityErrorEvent;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.text.StyleSheet;

import peace.data.Dimensions;
import peace.gui.controls.scroll.Scrollpane;
import peace.util.Logger;

/**
* шлем после окончания рендеринга html 
*/
[Event (name="render", type="flash.events.Event")]

/**
 * Слой над Htmllooker для загрузки xhtml по ссылкам 
 */
public class Browser extends Sprite
{
	
	/**
	 * кешируем css
	 */
	public var css:StyleSheet;
	/**
	 * открываем лоадер для кастомных прогрессбаров <br>
	 * 
	 * @example
	 * <listing>
	 * var p:CustomProgressbar = new CustomProgressbar();
	 * var b:Browser = new Browser(new StyleSheet());
	 * b.progressbar = p;
	 * b.urlLoader.addEventListener(ProgressEvent.PROGRESS, onProgress,false,0,true);
	 * b.url = "http://yandex.ru"
	 * </listing>
	 */	
	public var urlLoader:URLLoader = new URLLoader();
	/**
	 * html-процессор браузера. <br>
	 * <b>Важно!</b> Не работать с looker в обход интерфейса браузера!
	 */	
	public var looker:Htmllooker = new Htmllooker();
	/**
	 * кешируем размеры
	 */
	protected var size:Dimensions = new Dimensions(); 	
	/**
	 * текущая ссылка на html
	 */		
	protected var _url:String;

	protected var _scrollpane:Scrollpane;
 	protected var _progressbar:DisplayObject;
 	protected var _progressbarVisible:Boolean = false;

	/**
	 * 
	 * @param css
	 * @param scrollpane
	 * @param progressbar
	 * 
	 */	
	public function Browser (css:StyleSheet=null, scrollpane:Scrollpane=null, progressbar:DisplayObject=null)
	{
		this.css = css;
		this.scrollpane = scrollpane;
		this.progressbar = progressbar;
		
		urlLoader.addEventListener(Event.COMPLETE, onLoadContentComplete, false,0,true);
		urlLoader.addEventListener(IOErrorEvent.IO_ERROR, onLoadContentError, false,0,true);
		urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onLoadContentError, false,0,true);
	}
	
	/**
	 * Передаем html-строку
	 *  
	 * @param str
	 * 
	 */	
	public function set html(str:String):void
	{
		if (!str) return;
		
		_url = null;

		if (urlLoader)
		{
			try
			{
				urlLoader.close();	
			}
			catch (error:Error){}
		}
		
		_progressbarVisible = false;
		if (_progressbar)
		{
	 		_progressbar.visible = false;
		}

		looker.update (stringToXml(str), css);
		
		dispatchEvent(new Event(Event.RENDER));
	}
	/**
	 * Передаём request
	 * @param r
	 * 
	 */		
	public function set request (r:URLRequest):void
	{
		_url = r.url;
		
		urlLoader.load(r);
		
		_progressbarVisible = true;
		if (_progressbar)
		{
	 		_progressbar.visible = true;
		}
	}
	/**
	 * Передаём ссылку на html
	 * @param s
	 * 
	 */		
	public function set url (s:String):void
	{
		if (!s) return;
		
		_url = s;
		
		urlLoader.load(new URLRequest(_url));
		
		_progressbarVisible = true;
		if (_progressbar)
		{
	 		_progressbar.visible = true;
		}
	}
	/**
	 * 
	 * @return 
	 * 
	 */	
	public function get url ():String
	{
		return _url;
	}

	/**
	 * Добавляем прогрессбар, если нужен 
	 *  
	 * @param d DisplayObject
	 * 
	 */	
	public function set progressbar (d:DisplayObject):void
	{
		if (d == _progressbar) return;
		
		if (_progressbar && contains(_progressbar))
		{
			removeChild(_progressbar)
		}
		
		_progressbar = d;
		
		if (_progressbar)
		{
			addChild(_progressbar);
			_progressbar.visible = _progressbarVisible;
		}
	}
	/**
	 * Добавляем скроллпейн, если нужен
	 *  
	 * @param s
	 * 
	 */	
	public function set scrollpane (s:Scrollpane):void
	{
		if (_scrollpane && s == _scrollpane) return;
		
		if (_scrollpane && contains(_scrollpane))
		{
			removeChild(_scrollpane);
		}
		
		_scrollpane = s;

		if (size.width > 0)
		{
			this.width = size.width;
		}
		if (size.height > 0)
		{
			this.height = size.height;
		}

		if (! s)
		{
			addChildAt(looker, 0);
		}
		else
		{
			addChildAt(s, 0);
			s.content = looker;
		}
	}

	override public function set width(value:Number):void
	{
		size.width = value;
		
		if (_scrollpane)
		{
			looker.width = size.width - _scrollpane.vbar.width;
			_scrollpane.width = size.width;
		}
		else
		{
			looker.width = size.width;
		}
		
		if (_progressbar)
		{
			_progressbar.x = (value - _progressbar.width)/2;
		}
	}
	
	override public function set height(value:Number):void
	{
		size.height = value;
		
		if (_scrollpane)
		{
			_scrollpane.height = size.height;
		}
		
		looker.height = size.height - 1; // сука режет на пиксель почемуто
		
		if (_progressbar)
		{
			_progressbar.y = (value - _progressbar.height)/2;
		}
	}
	
	

	private function onLoadContentComplete (e:Event):void
	{
		var xml:XML = stringToXml(urlLoader.data);
		if (xml)
		{
			looker.update (xml, css);
		}
		
		_progressbarVisible = false;
		if (_progressbar)
		{
			_progressbar.visible = false;
		}
		
		dispatchEvent(new Event(Event.RENDER));
	}
	
	private function onLoadContentError (e:ErrorEvent):void
	{
		Logger.error(this, ":", e.text)
		
		looker.update (XML("<body>" + e.text + "</body>"), css);
		
		_progressbarVisible = false;
		if (_progressbar)
		{
			_progressbar.visible = false;
		}
		
		dispatchEvent(new Event(Event.RENDER));
	}
	/**
	 * 
	 * @param s
	 * @return 
	 * 
	 */	
	protected function stringToXml (s:String):XML
	{
		// поддерживаем важные символьные объекты (не поддерживаемые fp)
		// по именам (по номерам все работают и так)
		s = s.replace(/&nbsp;/gi, "&#160;");		
		s = s.replace(/&laquo;/gi, "«");		
		s = s.replace(/&raquo;/gi, "»");		
		s = s.replace(/&mdash;/gi, "—");	
		
		return  XML(s);
	}
	

}

}
